package pl.sind.http.oauth;

import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import pl.sind.http.HttpConnector;
import pl.sind.http.HttpRequest;
import pl.sind.http.auth.AuthenticationStrategy;

public class OAuthAuthenticationStrategy implements AuthenticationStrategy {

	private static final String ACCESS_TOKEN_ENDPOINT_URL = null;
	private static final String REQUEST_TOKEN_ENDPOINT_URL = null;
	private String consumerKey;
	private String consumerSecret;
	private String accessToken;
	private String tokenSecret;

	private boolean ready = false;

	private OAuthConsumer consumer;

	private OAuthProvider provider;
	private Class<?> connectorType;

	public OAuthAuthenticationStrategy(String consumerKey,
			String consumerSecret, String accessToken, String tokenSecret) {
		this(consumerKey, consumerSecret);
		this.accessToken = accessToken;
		this.tokenSecret = tokenSecret;
	}

	public void initialize(HttpConnector<?> connector) {
		if (!ready) {
			connectorType = connector.getTarget();
			consumer = OAuthConsumerFactory.getConsumer(connectorType,
					consumerKey, consumerSecret);
			consumer.setTokenWithSecret(accessToken, tokenSecret);
		}
		ready = true;
	}

	public OAuthAuthenticationStrategy(String consumerKey, String consumerSecret) {
		super();
		this.consumerKey = consumerKey;
		this.consumerSecret = consumerSecret;
	}

	public void perform(HttpRequest<?> con) {
		if (ready) {
			try {
				consumer.sign(con.unwrap());
			} catch (OAuthMessageSignerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (OAuthExpectationFailedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (OAuthCommunicationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			throw new RuntimeException("buuuu");
		}
	}

	public String fetchRequestToken(String website) throws OAuthException {
		OAuthProvider provider = getProvider(website);
		return provider.retrieveRequestToken(consumer, OAuth.OUT_OF_BAND);
	}

	private OAuthProvider getProvider(String website) {
		if (provider == null) {
			provider = OAuthProviderFactory.getProvider(connectorType,
					REQUEST_TOKEN_ENDPOINT_URL, ACCESS_TOKEN_ENDPOINT_URL,
					website);
		}
		return provider;
	}

	public void fetchAccessToken(String website, String code)
			throws OAuthException {
		OAuthProvider provider = getProvider(website);
		provider.retrieveAccessToken(consumer, code);
	}

}
